package com.gtvtv.sparkdesksdk.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gtvtv.sparkdesksdk.model.request.agent.AgentRequest;
import com.gtvtv.sparkdesksdk.model.request.agent.AgentRequestBody;
import com.gtvtv.sparkdesksdk.model.request.agent.AgentRequestHeader;
import com.gtvtv.sparkdesksdk.model.response.agent.AgentResponse;
import lombok.AllArgsConstructor;
import okhttp3.OkHttpClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@AllArgsConstructor
public class AgentClient {
    
    public String apiKey;

    public String apiSecret;

    private String apiUrl;

    public OkHttpClient client = new OkHttpClient.Builder().build();

    private static final ObjectMapper objectMapper = new ObjectMapper();

    public AgentClient() {
    }

    public AgentClient(String apiKey, String apiSecret, String apiUrl) {
        this.apiKey = apiKey;
        this.apiSecret = apiSecret;
        this.apiUrl = apiUrl;
    }

    /**
     * 发送请求并解析响应
     */
    public AgentResponse sendRequest(AgentRequest request) throws IOException {
        HttpURLConnection connection = null;
        try {
            // 创建URL连接
            URL url = new URL(apiUrl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");

            // 设置授权头
            Map<String, String> headers = request.getHeaders();
            for (Map.Entry<String, String> header : headers.entrySet()) {
                connection.setRequestProperty(header.getKey(), header.getValue());
            }

            // 启用输出流
            connection.setDoOutput(true);

            // 序列化请求体
            try (OutputStream os = connection.getOutputStream()) {
                objectMapper.writeValue(os, request.getBody());
            }

            // 获取响应状态
            int responseCode = connection.getResponseCode();
            if (responseCode >= 200 && responseCode < 300) {
                // 解析成功响应
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {

                    return objectMapper.readValue(br, AgentResponse.class);
                }
            } else {
                // 尝试解析错误响应
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8))) {

                    // 尝试解析为AgentResponse
                    try {
                        return objectMapper.readValue(br, AgentResponse.class);
                    } catch (Exception e) {
                        // 无法解析为结构化的错误响应
                        StringBuilder errorResponse = new StringBuilder();
                        String line;
                        while ((line = br.readLine()) != null) {
                            errorResponse.append(line);
                        }
                        throw new IOException("API请求失败: " + responseCode + " - " + errorResponse);
                    }
                }
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * 流式响应处理
     */
    public void processStreamingResponse(AgentRequestBody requestBody, StreamCallback callback) throws IOException {
        // 启用流式响应
        requestBody.setStream(true);

        AgentRequestHeader header = new AgentRequestHeader(apiKey, apiSecret);
        AgentRequest request = new AgentRequest(header, requestBody);

        HttpURLConnection connection = null;
        try {
            URL url = new URL(apiUrl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");

            // 设置授权头
            Map<String, String> headers = request.getHeaders();
            for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
                connection.setRequestProperty(headerEntry.getKey(), headerEntry.getValue());
            }

            // 启用输出流
            connection.setDoOutput(true);

            // 发送请求
            try (OutputStream os = connection.getOutputStream()) {
                objectMapper.writeValue(os, requestBody);
            }

            // 处理流式响应
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {

                String line;
                while ((line = reader.readLine()) != null) {
                    // 跳过空行
                    if (line.trim().isEmpty()) continue;

                    // 解析SSE格式的数据
                    if (line.startsWith("data: ")) {
                        String json = line.substring(6).trim();
                        if (json.equals("[DONE]")) {
                            callback.onComplete();
                            break;
                        }

                        try {
                            AgentResponse response = objectMapper.readValue(json, AgentResponse.class);
                            callback.onData(response);
                        } catch (Exception e) {
                            callback.onError(new IOException("解析错误: " + json, e));
                        }
                    }
                }
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * 流式响应回调接口
     */
    public interface StreamCallback {
        void onData(AgentResponse response);

        void onError(IOException e);

        void onComplete();
    }


}